#ifndef MANGOS_WAYPOINTMANAGER_H
#define MANGOS_WAYPOINTMANAGER_H

#include "Common.h"
#include <vector>
#include <string>
#include "Utilities/UnorderedMapSet.h"
#include "Policies/Singleton.h"

#define MAX_WAYPOINT_TEXT 5
struct WaypointBehavior
{
public:
							WaypointBehavior() {}
							WaypointBehavior(const WaypointBehavior &b);
public://
	bool					isEmpty();

public:
    uint32					emote;
    uint32					spell;
    int32					textid[MAX_WAYPOINT_TEXT];
    uint32					model1;
    uint32					model2;
};

struct WaypointNode
{
public://
							WaypointNode() : x(0.0f), y(0.0f), z(0.0f), orientation(0.0f), delay(0), script_id(0), behavior(NULL) {}
							WaypointNode(float _x, float _y, float _z, float _o, uint32 _delay, uint32 _script_id, WaypointBehavior * _behavior)
								: x(_x), y(_y), z(_z), orientation(_o), delay(_delay), script_id(_script_id), behavior(_behavior) {}

public:///
    float					x;
    float					y;
    float					z;
    float					orientation;
    uint32					delay;
    uint32					script_id;                                      // Added may 2010. WaypointBehavior w/DB data should in time be removed.
    WaypointBehavior *		behavior;
							
};

typedef std::vector<WaypointNode> WaypointPath;

class WaypointManager
{
public:
							WaypointManager() {}
							~WaypointManager() { Unload(); }

public:///
    void					Load();
    void					Unload();

    void					Cleanup();

    WaypointPath *			GetPath(uint32 id)
    {
        WaypointPathMap::iterator itr = m_pathMap.find(id);
        return itr != m_pathMap.end() ? &itr->second : NULL;
    }

    WaypointPath *			GetPathTemplate(uint32 entry)
    {
        WaypointPathTemplateMap::iterator itr = m_pathTemplateMap.find(entry);
        return itr != m_pathTemplateMap.end() ? &itr->second : NULL;
    }

    void					AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
    void					AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
    uint32					GetLastPoint(uint32 id, uint32 default_notfound);
    void					DeleteNode(uint32 id, uint32 point);
    void					DeletePath(uint32 id);
    void					SetNodePosition(uint32 id, uint32 point, float x, float y, float z);
    void					SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text);
    void					CheckTextsExistance(std::set<int32>& ids);

private:
    void					_addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
    void					_clearPath(WaypointPath &path);

private:
    typedef UNORDERED_MAP<uint32, WaypointPath> WaypointPathMap;
    WaypointPathMap			m_pathMap;
    typedef UNORDERED_MAP<uint32, WaypointPath> WaypointPathTemplateMap;
    WaypointPathTemplateMap m_pathTemplateMap;
};

#define sWaypointMgr MaNGOS::Singleton<WaypointManager>::Instance()

#endif
